package com.ecgsystem.connection;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.kxml2.kdom.Element;
import org.kxml2.kdom.Node;
import org.xmlpull.v1.XmlPullParserException;

import android.util.Log;

import com.ecgsystem.activity.PatientInfo;
import com.ecgsystem.activity.StoredSignal;
import com.ecgsystem.constants.Constants;
import com.ecgsystem.patient.HistoryRecord;

/**
 * TODO Put here a description of what this class does.
 * 
 * @author ANHTUAN. Created Sep 24, 2012.
 */
public class Connection implements Constants {
	/**
	 * TODO Put here a description of this field.
	 */
	public String realID = "";
	private PatientInfo patientList[];
	private HistoryRecord[] historyRecordList;

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param pos
	 * @return HistoryRecord
	 */
	public HistoryRecord getHistoryRecord(final int pos) {
		return this.historyRecordList[pos];
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param historyRecordList
	 */
	public void setHistoryRecordList(final HistoryRecord[] historyRecordList) {
		this.historyRecordList = historyRecordList;
	}

	private final SoapSerializationEnvelope envelope;

	/**
	 * TODO Put here a description of what this constructor does.
	 * 
	 */
	public Connection() {
		this.envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		this.envelope.dotNet = true;
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param username
	 * @param password
	 * @return int
	 */
	public int login(final String username, final String password) {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME1);
		SoapObject response = null;

		PropertyInfo nameProperty = new PropertyInfo();
		nameProperty.setName("username");
		nameProperty.setValue(username);
		nameProperty.setType(String.class);
		request.addProperty(nameProperty);

		PropertyInfo passProperty = new PropertyInfo();
		passProperty.setName("password");
		passProperty.setValue(password);
		passProperty.setType(String.class);
		request.addProperty(passProperty);

		this.envelope.setOutputSoapObject(request);
		this.envelope.headerOut = addheader();

		HttpTransportSE transport = new HttpTransportSE(URL);

		try {
			transport.call(SOAP_ACTION1, this.envelope);
			response = (SoapObject) this.envelope.getResponse();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return CONNECTION_ERR;
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return CONNECTION_ERR;
		}

		if (response == null)
			return WRONG_PASSWD;

		// SoapObject ob = (SoapObject)response.getProperty(0);

		int permission = Integer.parseInt(response.getProperty("permission")
				.toString());

		this.realID = response.getProperty("realID").toString();

		if (permission > 2)
			return WRONG_PASSWD;

		return 0;
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @return Element[]
	 */
	public static Element[] addheader() {
		Element[] header = new Element[1];
		header[0] = new Element()
				.createElement(
						"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
						"Security");
		header[0].setAttribute(null, "mustUnderstand", "1");
		Element usernametoken = new Element()
				.createElement(
						"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
						"UsernameToken");
		// usernametoken.addChild(Node.TEXT,"");
		usernametoken
				.setAttribute(
						"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd",
						"Id", "UsernameToken-4");
		header[0].addChild(Node.ELEMENT, usernametoken);
		Element username = new Element().createElement(null, "n0:Username");
		username.addChild(Node.TEXT, "username_value");
		// username.setPrefix("n0", null);
		usernametoken.addChild(Node.ELEMENT, username);
		Element pass = new Element().createElement(null, "n0:Password");
		// pass.setPrefix("n0",null);
		pass.setAttribute(
				null,
				"Type",
				"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
		pass.addChild(Node.TEXT, "password_value");

		usernametoken.addChild(Node.ELEMENT, pass);
		return header;
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @return PatientInfo[]
	 */
	public ArrayList<HashMap<String, String>> getPatientList() {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME2);
		SoapObject response = null;

		ArrayList<HashMap<String, String>> patientListArr = new ArrayList<HashMap<String, String>>();

		this.envelope.setOutputSoapObject(request);

		HttpTransportSE transport = new HttpTransportSE(URL);

		try {
			transport.call(SOAP_ACTION2, this.envelope);
			response = (SoapObject) this.envelope.getResponse();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		if (response == null){
			return null;
		}

		int count = response.getPropertyCount();
		
		for (int i = 0; i < count; i++) {
			HashMap<String, String> patient = new HashMap<String, String>();

			SoapObject patientOb = (SoapObject) response.getProperty(i);

			patient.put(TAG_PATIENT_ID, patientOb.getProperty("patientID")
					.toString());
			patient.put(TAG_PATIENT_NAME, patientOb.getProperty("patientName")
					.toString());
			patient.put(TAG_PATIENT_AGE, patientOb.getProperty("dateOfBirth")
					.toString());
			patient.put(TAG_GENDER, patientOb.getProperty("sex").toString());

			patientListArr.add(patient);
		}

		return patientListArr;
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param patientID
	 * @return String[]
	 */
	public String[] getRecordHistoryDayList(final String patientID) {
		String[] dayList = { "" };

		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME3);
		SoapObject response;

		PropertyInfo idProperty = new PropertyInfo();
		idProperty.setName("patientID");
		idProperty.setValue(patientID);
		idProperty.setType(String.class);
		request.addProperty(idProperty);

		this.envelope.setOutputSoapObject(request);

		HttpTransportSE transport = new HttpTransportSE(URL);

		try {
			transport.call(SOAP_ACTION3, this.envelope);
			response = (SoapObject) this.envelope.getResponse();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

		if (response == null)
			return null;

		int count = response.getPropertyCount();
		this.historyRecordList = new HistoryRecord[count];
		dayList = new String[count];

		for (int i = 0; i < count; i++) {
			HistoryRecord record = new HistoryRecord();

			SoapObject recordOb = (SoapObject) response.getProperty(i);
			record.setRecordID(recordOb.getProperty("recordID").toString());
			record.setPatientID(recordOb.getProperty("patientID").toString());
			record.setDateTime(recordOb.getProperty("dateTimeOfRecord")
					.toString());
			record.setRecordDir(recordOb.getProperty("recordDir").toString());

			this.historyRecordList[i] = record;

			dayList[i] = record.getDateTime() + " : " + record.getRecordID();
		}

		return dayList;
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param recordID
	 */
	public void getRecord(final String recordID) {
		String record = "";

		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME4);
		SoapPrimitive response = null;

		PropertyInfo idProperty = new PropertyInfo();
		idProperty.setName("recordID");
		idProperty.setValue(recordID);
		idProperty.setType(String.class);
		request.addProperty(idProperty);

		this.envelope.setOutputSoapObject(request);

		HttpTransportSE transport = new HttpTransportSE(URL);

		try {
			transport.call(SOAP_ACTION4, this.envelope);
			response = (SoapPrimitive) this.envelope.getResponse();

			record = response.toString();
			Log.i("received", record);
			StringTokenizer st = new StringTokenizer(record, ",");
			while (st.hasMoreTokens()) {
				st.nextToken();
				StoredSignal.QueueDraw[0].add(Float.valueOf(Float.valueOf(st
						.nextToken())));
			}

			return;
		} catch (IOException e) {
			StoredSignal.QueueDraw[0] = null;
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			StoredSignal.QueueDraw[0] = null;
			e.printStackTrace();
		} catch (ClassCastException e) {
			StoredSignal.QueueDraw[0] = null;
			e.printStackTrace();
		} catch (Exception e) {
			StoredSignal.QueueDraw[0] = null;
			e.printStackTrace();
		}
		StoredSignal.QueueDraw[0] = null;
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param recordID
	 * @return String
	 */
	public String getDirOfRecord(final String recordID) {
		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME7);
		SoapObject response = null;

		PropertyInfo idProperty = new PropertyInfo();
		idProperty.setName("recordID");
		idProperty.setValue(recordID);
		idProperty.setType(String.class);
		request.addProperty(idProperty);

		this.envelope.setOutputSoapObject(request);

		HttpTransportSE transport = new HttpTransportSE(URL);
		try {
			transport.call(SOAP_ACTION7, this.envelope);
			response = (SoapObject) this.envelope.getResponse();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XmlPullParserException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return response.getProperty("recordDir").toString();
	}

	/**
	 * TODO Put here a description of what this method does.
	 * 
	 * @param recordID
	 */
	public void getRecord12(String recordID) {
		String resultStr;
		boolean hasRecord[] = { false, false, false, false, false, false,
				false, false, false, false, false, false }; // danh dau dao
															// trinh nao duoc do

		SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME5);
		SoapPrimitive response = null;

		PropertyInfo idProperty = new PropertyInfo();
		idProperty.setName("recordid");
		idProperty.setValue(recordID);
		idProperty.setType(String.class);
		request.addProperty(idProperty);

		this.envelope.setOutputSoapObject(request);

		HttpTransportSE transport = new HttpTransportSE(URL);

		try {
			transport.call(SOAP_ACTION5, this.envelope);
			response = (SoapPrimitive) this.envelope.getResponse();
			resultStr = response.toString();

			Log.i("receivedSignal", resultStr);
			StringTokenizer st = new StringTokenizer(resultStr, "\t");

			// Doc 12 tin hieu dau de xem dao trinh nao duoc do
			for (int i = 0; i < 12; i++) {
				if (st.nextToken().equals("1")) {
					hasRecord[i] = true;
				} else {
					StoredSignal.QueueDraw[i] = null;
				}
			}

			while (st.hasMoreTokens()) {
				st.nextToken(); // bo qua thoi gian
				for (int i = 0; i < 12; i++) {
					Float signal = Float.valueOf(Float.valueOf(st.nextToken()));
					if (hasRecord[i]) {
						StoredSignal.QueueDraw[i].add(signal);
					}
				}
			}
		} catch (XmlPullParserException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
